package com.muyu.util;

import org.springframework.stereotype.Component;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName: Uploader
 * @Author: Zirun.Xin
 * @Date: 2025/4/29 下午3:39
 * @Version: 1.0
 * @Description: 上传者工具
 */
@Component
public class Uploader {

    /**
     * 将指定文件添加到ZIP输出流中
     *
     * @param filePath 要压缩的文件的绝对路径
     * @param zipOut   ZIP输出流，用于写入压缩数据
     * @throws IOException              如果发生I/O错误，包括：
     *                                  - 文件不存在或不可读
     *                                  - 无法创建ZIP条目
     *                                  - 写入ZIP流失败
     * @throws IllegalArgumentException 如果filePath为null或空字符串
     * @apiNote 此方法会自动关闭文件输入流，但不会关闭传入的zipOut流，
     * 调用方需要负责关闭zipOut流
     */
    public void fileToZip(String filePath, ZipOutputStream zipOut) throws IOException {
        // 参数校验
        if (filePath == null || filePath.trim().isEmpty()) {
            throw new IllegalArgumentException("文件路径不能为空");
        }
        if (zipOut == null) {
            throw new IllegalArgumentException("ZIP输出流不能为null");
        }

        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException(String.format("文件不存在: %s", filePath));
        }
        if (!file.isFile()) {
            throw new IOException(String.format("路径不是文件: %s", filePath));
        }
        if (!file.canRead()) {
            throw new IOException(String.format("文件不可读: %s", filePath));
        }

        // 使用try-with-resources确保流被正确关闭
        try (FileInputStream fileInputStream = new FileInputStream(file);
             BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 1024 * 10)) {

            // 创建zip条目
            ZipEntry zipEntry = new ZipEntry(file.getName());
            zipOut.putNextEntry(zipEntry);

            // 缓冲区大小可根据实际需求调整
            byte[] buffer = new byte[1024 * 10];
            int bytesRead;

            // 读取文件内容并写入ZIP流
            while ((bytesRead = bufferedInputStream.read(buffer)) != -1) {
                zipOut.write(buffer, 0, bytesRead);
            }

            // 关闭当前条目
            zipOut.closeEntry();
        } catch (IOException e) {
            // 添加更多上下文信息后重新抛出
            throw new IOException(String.format("压缩文件失败: %s", filePath), e);
        }
    }
}
